package Thread;

import java.util.concurrent.TimeUnit;

/**
 * @author 逸尘风清
 * @date 2021/4/27
 * @time 10:25
 * 描述：
 */

/**
 * 锁定某对象o，如果o的属性发生改变，不影响锁的使用
 * 但是如果o变成另外一个对象，则锁定的对象发生改变
 * 应该避免将锁定对象的引用变成另外的对象
 */
public class SyncSameObject {
    /*final*/ Object o = new Object();

    void m() {
        synchronized(o) {
            while(true) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName());
            }
        }
    }

    public static void main(String[] args) {
        SyncSameObject t = new SyncSameObject();
        //启动第一个线程
        new Thread(t::m, "t1").start();

        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //创建第二个线程
        Thread t2 = new Thread(t::m, "t2");

        /**
         * 重新实例化对象赋值给o，则o对象发生改变，所以t2线程得以执行。
         * 如果注释掉这句话，线程2将永远得不到执行机会。因为t1之前将对象o锁了，一直在循环，没有释放锁，t2就拿不到锁
         * 如果不想对象被改变，则在属性添加 final
         */
        t.o = new Object();

        t2.start();

    }

}
